﻿using DxfOk;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace DxfLib
{
    public static class DxfUtils
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger
          (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private static Regex regWithOk = new Regex(@".+\s*ok\s*", RegexOptions.IgnoreCase);
        private static Regex regOkOnly = new Regex(@"\s*ok\s*", RegexOptions.IgnoreCase);

        private static Dictionary<string, string> dicIndexFolder = ReadDicIndexFolder();

        private static Dictionary<string, string> ReadDicIndexFolder()
        {
            var dic = new Dictionary<string, string>();
            foreach (string line in File.ReadAllLines(LibConstants.FolderIndexFile)
                .Where(x => x.Length > 5).Reverse())
            {
                var parts = line.Trim().Split(new char[] { '\t' });
                string index = parts[0].Trim();
                if (!dic.ContainsKey(index))
                    dic[index] = parts[1].Trim();
            }
            return dic;
        }
        public static string? searchFolderByIndex(string index)
        {
            index = index.Trim();
            if (dicIndexFolder.ContainsKey(index))
                return dicIndexFolder[index];
            else
                return null;
        }

        public static bool ContainsOk(string s)
        {
            return regWithOk.IsMatch(s);
        }

        public static bool FileNameContainsOk(string fileName)
        {
            return ContainsOk(Path.GetFileNameWithoutExtension(fileName));
        }

        public static void CheckAllRealFoldersStatus()
        {
            foreach (string folder in DxfUtils.AllRealFolders)
            {
                AreAllFilesUnderFolderOk(folder);
            }
        }

        public static void MarkFolderStatus(string folder, bool ok)
        {
            if (Directory.Exists(folder))
            {
                string lastLayerFolder = Path.GetFileName(folder);//TODO: ut
                string addFile = Path.Combine(folder, LibConstants.AddOk);
                string removeFile = Path.Combine(folder, LibConstants.DelOk);
                try
                {
                    if (ok)
                    {
                        if (!File.Exists(addFile) && !DxfUtils.ContainsOk(lastLayerFolder))
                        {
                            if (!DxfUtils.AllToAddOkFolders.Contains(folder))
                            {
                                DxfUtils.AllToAddOkFolders.Add(folder);
                            }
                            File.Create(addFile).Close();
                        }
                        if (File.Exists(removeFile))
                        {
                            File.Delete(removeFile);
                        }
                        if (DxfUtils.AllToRmOkFolders.Contains(folder))
                        {
                            DxfUtils.AllToAddOkFolders.Remove(folder);
                        }
                    }
                    else
                    {
                        if (!File.Exists(removeFile) && DxfUtils.ContainsOk(lastLayerFolder))
                        {
                            File.Create(removeFile).Close();
                            if (!DxfUtils.AllToRmOkFolders.Contains(folder))
                            {
                                DxfUtils.AllToRmOkFolders.Add(folder);
                            }
                        }
                        if (File.Exists(addFile))
                        {
                            File.Delete(addFile);
                        }
                        if (DxfUtils.AllToAddOkFolders.Contains(folder))
                        {
                            DxfUtils.AllToAddOkFolders.Remove(folder);
                        }

                    }
                }
                catch (Exception ex)
                {
                    log.Error($"标记文件夹{folder} ok={ok} 时出错 {ex.Message}");
                }
            }
        }

        public static bool AreAllFilesUnderFolderOk(string folderFull)
        {
            bool ready = Directory.GetFiles(folderFull, LibConstants.FileExtensionToValidate, SearchOption.AllDirectories)
                .All(x => FileNameContainsOk(x));
            MarkFolderStatus(folderFull, ready);
            return ready;
        }

        public static string RemoveOk(string s)
        {
            if (regOkOnly.IsMatch(s))
                return regOkOnly.Replace(s, "");
            else
                return s;
        }


        public static string SetOk(string s)
        {
            if (regOkOnly.IsMatch(s))
                return s;
            else
                return s + " ok";
        }
        public static bool AreSameIgnoreOk(string a, string b)
        {
            return string.Equals(RemoveOk(a), RemoveOk(b), StringComparison.OrdinalIgnoreCase);
        }

        public static string? SearchRealDir(string d)
        {
            string fullDir = Path.GetFullPath(d);
            log.Debug($"SearchRealDir for [{fullDir}]");
            string? fuzzyFound = AllRealFolders.FirstOrDefault(x => AreSameIgnoreOk(x, fullDir));
            if (fuzzyFound != null)
                fuzzyFound = Path.GetFullPath(fuzzyFound);
            log.Debug($"fuzzyFound dir=[{fuzzyFound}]");
            return fuzzyFound;
        }

        public static HashSet<string> AllRealFolders;
        public static HashSet<string> AllProtectedFolders;
        //public static Dictionary<string, bool> dicRealFoldersStatus = new Dictionary<string, bool>();
        public static HashSet<string> AllToAddOkFolders = new HashSet<string>();
        public static HashSet<string> AllToRmOkFolders = new HashSet<string>();

    }
}